<template>
  <!-- 签约分类弹窗 -->
  <el-dialog
    v-model="visible"
    :show-close="false"
    :append-to-body="true"
    :close-on-click-modal="false"
    top="10vh"
    width="70%"
    class="component-signing-category header-no-padding"
    @close="closePopup"
  >
    <div class="signing-categiries-content">
      <!-- 标题 -->
      <div class="title">
        <div class="text">
          <span class="stress">*</span>
          {{ applyForSign ? $t('shopProcess.addSigningCategory') : $t('shopProcess.editSigningCategory') }}
        </div>
        <div class="tips">
          {{ $t('shopProcess.signingCategoryTips') }}，
          {{ $t('shopProcess.preSigned') }}
          <span class="bold">{{ signingCount }}</span>
          {{ $t('shopProcess.piece') }}{{ $t('shopProcess.category') }}，
          {{ $t('shopProcess.application') }}
          <span class="bold">{{ applyingCategoryNum }}</span>
          {{ $t('shopProcess.piece') }}{{ $t('shopProcess.category') }}，
          {{ $t('shopProcess.chosen') }}
          <span class="bold">{{ signCategories.length }}</span>
          {{ $t('shopProcess.piece') }}{{ $t('shopProcess.category') }}，
          {{ $t('shopProcess.mostAdd') }}
          <span class="bold">200</span>
          {{ $t('shopProcess.piece') }}{{ $t('shopProcess.category') }}
        </div>
        <div
          class="close-btn"
          @click="closePopup"
        >
          <el-icon><Close /></el-icon>
        </div>
      </div>

      <!-- 内容 -->
      <div class="content">
        <div class="left-box">
          <div class="search-box">
            <input
              v-model="categoryName"
              class="search-input"
              :placeholder="$t('publics.categoryInputTips')"
            >
          </div>
          <div
            v-loading="loading"
            element-loading-text="数据处理中..."
          >
            <el-tree-v2
              ref="categoryTreeRef"
              :data="tree.treeData"
              :filter-method="filterNode"
              :props="categoryListTreeProps"
              class="filter-tree"
              show-checkbox
              highlight-current
              icon-class="el-icon-arrow-right"
              :default-checked-keys="signCategories.map(el=> el.categoryId)"
              :height="522"
              @check="onCheckChange"
            >
              <template #default="{ node, data }">
                <el-tooltip
                  :content="data.grade === 2 ? data.categoryName + ' ' + data.deductionRate + '%' : data.categoryName"
                  placement="right"
                  effect="light"
                  :show-after="200"
                  class="custom-tree-node"
                >
                  <div
                    class="item-bar"
                  >
                    <div
                      v-rich="renderNode(node.label)"
                      class="label"
                    />
                  </div>
                </el-tooltip>
              </template>
            </el-tree-v2>
          </div>
        </div>

        <!-- 右边表格 -->
        <div
          ref="tableBoxRef"
          class="right-box table-box"
        >
          <el-table
            :data="signCategories"
            :header-cell-style="{height:'50px',background:'#F5F5F5',color:'#000','font-weight': '400'}"
          >
            <el-table-column
              prop="categoryName"
              :label="$t('shopProcess.categoryName')"
            />
            <el-table-column
              prop="parentName"
              :label="$t('shopProcess.parentCategoryName')"
            />
            <el-table-column
              prop="platformRate"
              :label="$t('shopProcess.categoryRate')"
            >
              <template #default="{ row }">
                <span v-if="row.platformRate || row.platformRate === 0">{{ row.platformRate }} %</span>
                <span v-else>--</span>
              </template>
            </el-table-column>
            <el-table-column
              prop="qualifications"
              :label="$t('shopProcess.categoryQualifications')"
              width="250px"
            >
              <template #default="scope">
                <div
                  :key="scope.row.qualifications"
                  class="business-qual"
                >
                  <imgs-upload
                    v-model="scope.row.qualifications"
                    :limit="2"
                    :prompt="false"
                  />
                </div>
              </template>
            </el-table-column>
            <el-table-column
              prop="address"
              :label="$t('sys.operation')"
              align="center"
            >
              <template #default="scope">
                <div
                  class="default-btn text-btn"
                  @click="deleteSelectedCategory(scope)"
                >
                  {{ $t('text.delBtn') }}
                </div>
              </template>
            </el-table-column>
          </el-table>
        </div>
      </div>

      <div class="btn-row foot-btn">
        <div
          class="default-btn"
          @click="closePopup"
        >
          {{ $t('remindPop.cancel') }}
        </div>
        <div
          class="default-btn primary-btn"
          @click="comfirmSubmit"
        >
          {{ $t('remindPop.confirm') }}
        </div>
      </div>
    </div>
  </el-dialog>
</template>

<script setup>
import { ElMessage, ElMessageBox } from 'element-plus'
import Ms from 'magic-string'

const props = defineProps({
  // 签约分类列表
  signCategoryList: {
    type: Array,
    default () {
      return []
    }
  },
  /**
   * 是否从商城信息申请签约
   * applyForSign=true时，请求可以签约的平台分类列表（已经签约的平台分类不会返回）
   */
  applyForSign: {
    type: Boolean,
    default: false
  },
  signingCount: {
    type: Number,
    default: 0
  }
})

const renderNode = (str) => {
  if (categoryName.value == '') return `<span>${str}</span>`
  const s = new Ms(str)
  const reg = new RegExp(categoryName.value, 'ig')
  let match
  while ((match = reg.exec(str)) != null) {
    const start = match.index
    const end = match.index + match[0].length
    s.update(start, end, `<span style='color: coral'>${match[0]}</span>`)
  }
  return s.toString()
}

// 搜索参数
const categoryName = ref('')
const categoryListTreeProps = reactive({
  value: 'categoryId',
  label: 'categoryName'
})

const filterNode = (value, node) => {
  if (value) {
    return node.categoryName.toLowerCase().includes(value.toLowerCase())
  } else {
    return node.categoryName
  }
}

const categoryTreeRef = ref(null)
watch(() => categoryName.value, (val) => {
  categoryTreeRef.value?.filter(val)
})

// 商城id
let shopId = null
// 已选分类父分类的id set集合
let signCategoryParentIdSet = null
// 已选分类
const signCategories = ref([])
const init = (shopIdPar) => {
  shopId = shopIdPar
  signCategoryParentIdSet = new Set()
  getPlatformCategory()
  queryCategoryContractInfo()
  // getIds(signCategories.value, 0)
}

const applyingCategoryNum = ref(0)
/**
 * 查询分类申请信息
 */
const queryCategoryContractInfo = () => {
  http({
    url: http.adornUrl('/prod/category/signingInfoByShopId'),
    method: 'get',
    params: http.adornParams({
      shopId,
      status: 0// 签约状态：1：已通过 0待审核 -1未通过
    })
  }).then(({ data }) => {
    applyingCategoryNum.value = data.length
  })
}

const loading = ref(false)
const visible = ref(false)
const categorgTreeData = ref([])
const categoryList = ref([])

const tree = computed(() => {
  const treeMap = new Map()
  const treeData = []
  categoryList.value.forEach(item => {
    item.isLeaf = true
    treeMap.set(item.categoryId, item)
  })
  categoryList.value.forEach(item => {
    if (item.parentId == 0) {
      treeData.push(item)
    } else {
      const parent = treeMap.get(item.parentId)
      if (!parent) {
        return
      }
      if (!parent.children) {
        parent.children = []
      }
      parent.isLeaf = false
      parent.children.push(item)
    }
  })
  return {
    treeMap,
    treeData
  }
})

// 总分类列表
const patformCategories = ref([])
/**
 * 获取平台分类列表，并转换成树形结构
 */
const getPlatformCategory = () => {
  loading.value = true
  const url = props.applyForSign ? '/platform/signingAuditing/listApplySigningCategory' : '/prod/category/platformCategory'
  http({
    url: http.adornUrl(url),
    method: 'get',
    params: http.adornParams({
      shopId,
      maxGrade: 2,
      status: 1
    })
  }).then(({ data }) => {
    loading.value = false
    if (data && data.length) {
      visible.value = true
      categoryList.value = data
    } else {
      ElMessageBox.confirm('当前商城已签约平台全部类目，暂无可新增签约类目', '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        showCancelButton: false,
        type: 'warning'
      }).then(() => {
        closePopup()
      })
    }
  }).catch(() => {
    visible.value = true
  })
}

// 已选分类id数组
const signCategoryIds = ref([])
// 已选分类父分类id数组
const signCategoryParentIds = ref([])
const getIds = (data, sts) => {
  signCategoryIds.value.splice(0, signCategoryIds.value.length)
  signCategoryParentIds.value.splice(0, signCategoryParentIds.value.length)
  data.forEach(el => {
    // 已选分类id
    signCategoryIds.value.push(el.categoryId)
    // 已选分类的父分类id
    signCategoryParentIdSet.add(el.parentId)
  })
  signCategoryParentIds.value = Array.from(signCategoryParentIdSet)
  if (sts === 1) {
    nextTick(() => {
      categoryTreeRef.value?.setCheckedKeys(signCategoryIds.value)
    })
  }
}

/**
 * 去除没有下级分类的类目
 */
const removeNotThirdCategoryItem = (treeData) => {
  const firstCategory = treeData
  const length = firstCategory.length
  for (let i = 0, index = 0; i < length; i++) {
    if (firstCategory[index].grade !== 2) {
      if (firstCategory[index].children && firstCategory[index].children.length > 0 && (firstCategory[index].children.some(item => item.children) || firstCategory[index].grade !== 0)) {
        const secondCategory = firstCategory[index].children
        firstCategory[index].children = removeNotThirdCategoryItem(secondCategory)
      } else {
        firstCategory.splice(index, 1)
        // 当前位置的元素已经被删除，当前位置索引不用++
        continue
      }
    }
    index++
  }
  return firstCategory
}

let message = false
/**
 * 对勾选到的数据逐一处理
 * @param nodeObj 节点数据
 * @param isExist 是否为选中状态
 * @returns {Promise<void>}
 */
const onCheckLevel = async (nodeObj, isExist) => {
  const isExistTwo = props.signCategoryList.some(item => item.categoryId === nodeObj.categoryId)
  if (nodeObj.grade !== 2) {
    return
  }

  if (isExist) {
    if (signCategories.value.length + props.signingCount === 200) {
      if (!message) {
        message = true
        ElMessage({
          message: $t('shopProcess.categoryAddMaxLimitTips'),
          type: 'error',
          duration: 1000,
          onClose: () => {
            message = false
          }
        })
      }
      getIds(signCategories.value, 1)
      return
    }
    if (isExistTwo) {
      return
    }
    const signCategory = {
      categoryId: nodeObj.categoryId,
      categoryName: nodeObj.categoryName,
      parentName: nodeObj.parentName || '',
      platformRate: nodeObj.deductionRate,
      categoryStatus: nodeObj.status,
      qualifications: ''
    }
    if (!nodeObj.parentName) {
      patformCategories.value.forEach(el => {
        if (el.categoryId === nodeObj.parentId) {
          signCategory.parentName = el.categoryName
        }
      })
    }
    signCategories.value.push(signCategory)
    signCategoryParentIdSet.add(nodeObj.parentId)
  } else {
    signCategories.value = deleteById(nodeObj.categoryId, signCategories.value)
  }
}

/**
 * 将勾选到的数据进行遍历
 * @param nodeObj 勾选到的当前节点数据
 * @param isExist 判断是否为选中状态
 * @returns {Promise<void>}
 */
const onHandleCheck = async (nodeObj, isExist) => {
  await onCheckLevel(nodeObj, isExist)
  if (nodeObj.children && nodeObj.children.length > 0) {
    for (const item of nodeObj.children) {
      await onCheckLevel(item, isExist)
      if (item.children && item.children.length > 0) {
        for (const childItem of item.children) {
          if (props.signCategoryList.length >= 200 && isExist) {
            await getIds(props.signCategoryList, 1)
            return
          }
          await onCheckLevel(childItem, isExist)
        }
      }
    }
  }
}

/**
 * 节点选中状态发生变化时的回调
 * @param {Object} nodeObj 传递给 data 属性的数组中该节点所对应的对象
 * @param {Boolean} nodeStatus 树目前的选中状态对象
 */
const onCheckChange = (_, treeNodeInfo) => {
  signCategories.value = treeNodeInfo.checkedNodes.filter(item => item.isLeaf)
}

/**
 * 根据id删除数组项
 * @param {Number} id 需要删除的id
 * @param {Array} list 目标数组
 * @return {Array}
 */
const deleteById = (id, list) => {
  for (let index = list.length - 1; index >= 0; index--) {
    if (list[index] && list[index].categoryId === id) {
      list.splice(index, 1)
    }
  }
  return list
}

/**
 * 删除已选分类
 */
const deleteSelectedCategory = (scope) => {
  const index = scope.$index
  signCategories.value.splice(index, 1)
  getIds(signCategories.value, 1)
}

/**
 * 确认
 */
const comfirmSubmit = () => {
  if (signCategories.value.length > 0) {
    signCategory()
  } else {
    ElMessage({
      message: $t('shopProcess.categorySigningNotEmpty'),
      type: 'error',
      duration: 1000
    })
  }
}

/**
 * 请求签约分类
 */
const signCategory = () => {
  const params = []
  signCategories.value.forEach(item => {
    const param = {
      categoryId: item.categoryId,
      rate: null,
      qualifications: item.qualifications ? item.qualifications : null
    }
    params.push(param)
  })
  const url = props.applyForSign ? '/platform/signingAuditing/addSigningCategory' : '/prod/category/signing'
  http({
    url: http.adornUrl(url),
    method: 'post',
    data: params,
    params: http.adornParams({
      shopId
    })
  }).then(() => {
    ElMessage({
      message: $t('remindPop.succeeded'),
      type: 'success',
      duration: 1000
    })
    closePopup()
  })
}

const emit = defineEmits(['closePopup'])
/**
 * 关闭弹窗
 */
const closePopup = () => {
  emit('closePopup', 'category')
}

const handleNodeClick = (nodeObj, nodeStatus) => {
  if (nodeStatus.level !== 3) return
  let keys = signCategories.value.map(item => item.categoryId)
  if (nodeStatus.checked) {
    for (let i = 0; i < keys.length; i++) {
      if (keys[i] === nodeObj.categoryId) {
        signCategories.value = signCategories.value.filter(item => item.categoryId !== nodeObj.categoryId)
        keys.splice(i, 1)
        break
      }
    }
  } else {
    if (signCategories.value.length + props.signingCount >= 200) {
      ElMessage({
        message: $t('shopProcess.categoryAddMaxLimitTips'),
        type: 'error',
        duration: 1000
      })
    } else {
      const signCategory = {
        categoryId: nodeObj.categoryId,
        categoryName: nodeObj.categoryName,
        parentName: nodeObj.parentName || '',
        platformRate: nodeObj.deductionRate,
        categoryStatus: nodeObj.status,
        qualifications: ''
      }
      if (!nodeObj.parentName) {
        patformCategories.value.forEach(el => {
          if (el.categoryId === nodeObj.parentId) {
            signCategory.parentName = el.categoryName
          }
        })
      }
      signCategories.value.push(signCategory)
      keys = keys.concat(nodeObj.categoryId)
    }
  }
  categoryTreeRef.value?.setCheckedKeys(keys)
}

defineExpose({
  init
})

</script>

<style lang="scss" scoped>
@use "index";
</style>
